/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.data.jdbc;

import io.iec.edp.caf.data.jdbc.handler.ResultSetHandler;
import io.iec.edp.caf.commons.dataaccess.DbType;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.*;
import java.util.List;
import java.util.Map;

/**
 * JDBC数据访问层接口
 *
 * @author wangyandong
 * @date 2021/05/12 16:55
 */
public interface Database extends AutoCloseable {

    /**
     * 获取当前数据库类型
     *
     * @return
     */
    public DbType getDbType();

    /**
     * 获取连接字符串
     *
     * @return
     */
    public String getConcatOperator() throws SQLException;

    /**
     * 获取SQL中创建GUID的函数
     *
     * @return
     */
    public String getNewIdFunc() throws SQLException;

    /**
     * 获取SQL中获取数据库当前时间的函数
     *
     * @return
     */
    public String getDBDataTimeFunc() throws SQLException;

    /**
     * 获取SQL中取字符串子串的函数
     *
     * @return
     */
    public String getSubStrFunc() throws SQLException;

    /**
     * 获取SQL中判断Null值的函数
     *
     * @return
     */
    public String getIsNullFunc() throws SQLException;

    /**
     * 获取SQL中取字符串长度的函数
     *
     * @return
     */
    public String getStrLenFunc() throws SQLException;

    /**
     * 是否在每次执行完SQL后自动关闭连接
     */
    public Boolean autoClose = null;

    /**
     * 开启事务
     */
    public void beginTrans() throws SQLException;


    /**
     * 关闭事务
     */
    public void commitTrans() throws SQLException;


    /**
     * 回滚事务
     */
    public void rollbackTrans() throws SQLException;


    /**
     * 执行 select 操作
     * <br>
     * 使用primary数据源
     *
     * @param sql    sql
     * @param clazz  bean类型
     * @param params 参数
     * @param <T>    泛型
     * @return result
     */
    public <T> T query(String sql, Class<T> clazz, Object... params) throws SQLException;

    /**
     * 执行 select 操作
     *
     * @param sql    sql
     * @param clazz  bean类型
     * @param params 参数
     * @param <T>    泛型
     * @return result
     */
    public <T> T query(String sql, Class<T> clazz, List<Object> params) throws SQLException;

    /**
     * 执行 select 操作
     *
     * @param sql     sql
     * @param handler 结果集处理器
     * @param params  参数
     * @param <T>     泛型
     * @return result
     */
    public <T> T query(String sql, ResultSetHandler<T> handler, Object... params) throws SQLException;

    /**
     * 执行 select 操作
     *
     * @param sql     sql
     * @param handler 结果集处理器
     * @param params  参数
     * @param <T>     泛型
     * @return result
     */
    public <T> T query(String sql, ResultSetHandler<T> handler, List<Object> params) throws SQLException;

    /**
     * 执行 select 操作 并转换为对象集合
     *
     * @param sql    sql
     * @param clazz  bean类型
     * @param params 参数
     * @param <T>    泛型
     * @return result
     */
    public <T> List<T> queryForList(String sql, Class<T> clazz, Object... params) throws SQLException;

    /**
     * 执行 select 操作 并转换为对象集合
     *
     * @param sql    sql
     * @param clazz  bean类型
     * @param params 参数
     * @param <T>    泛型
     * @return result
     */
    public <T> List<T> queryForList(String sql, Class<T> clazz, List<Object> params) throws SQLException;

    /**
     * 执行 select 操作 并转换为map
     *
     * @param sql    sql
     * @param params 参数
     * @return result
     */
    public Map<String, Object> queryForMap(String sql, Object... params) throws SQLException;

    /**
     * 执行 select 操作 并转换为map
     *
     * @param sql    sql
     * @param params 参数
     * @return result
     */
    public Map<String, Object> queryForMap(String sql, List<Object> params) throws SQLException;


    /**
     * 执行 select 操作 并转换为map集合
     *
     * @param sql    sql
     * @param params 参数
     * @return result
     */
    public List<Map<String, Object>> queryForMapList(String sql, Object... params) throws SQLException;

    /**
     * 执行 select 操作 并转换为map集合
     *
     * @param sql    sql
     * @param params 参数
     * @return result
     */
    public List<Map<String, Object>> queryForMapList(String sql, List<Object> params) throws SQLException;

    /**
     * 执行 INSERT、 UPDATE、 DELETE 操作
     *
     * @param sql    sql
     * @param params 参数
     * @return 受影响行数
     */
    public int update(String sql, Object... params) throws SQLException;

    /**
     * 执行 INSERT、 UPDATE、 DELETE 操作
     *
     * @param sql    sql
     * @param params 参数
     * @return 受影响行数
     */
    public int update(String sql, List<Object> params) throws SQLException;

    /**
     * 执行方法
     *
     * @param sql
     * @return
     * @throws SQLException
     */
    public Boolean execute(String sql) throws SQLException;

    /**
     * 执行方法
     *
     * @param sql
     * @return
     * @throws SQLException
     */
    public Boolean execute(String sql, List<Object> paramList) throws SQLException;

    /**
     * 参数化执行
     * 底层通过PreparedStatement实现
     *
     * @param sql
     * @param paramMap
     * @return
     */
    public Boolean execute(String sql, Map<String, Object> paramMap) throws SQLException;

    JdbcTemplate getJdbcTemplate();
}
